package com.rvalerio.foregroundappchecker;

import com.rvalerio.fgchecker.AppChecker;
import com.rvalerio.fgchecker.LogUtil;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.IntentParams;
import ohos.agp.window.dialog.ToastDialog;
import ohos.event.commonevent.CommonEventData;
import ohos.event.commonevent.CommonEventManager;
import ohos.event.commonevent.CommonEventSubscribeInfo;
import ohos.event.commonevent.CommonEventSubscriber;
import ohos.event.commonevent.MatchingSkills;
import ohos.event.intentagent.IntentAgent;
import ohos.event.intentagent.IntentAgentConstant;
import ohos.event.intentagent.IntentAgentHelper;
import ohos.event.intentagent.IntentAgentInfo;
import ohos.event.notification.NotificationHelper;
import ohos.event.notification.NotificationRequest;
import ohos.rpc.RemoteException;

import java.util.ArrayList;
import java.util.List;

import static com.rvalerio.foregroundappchecker.Constants.TIMEOUT;
import static com.rvalerio.foregroundappchecker.Constants.NOTIFICATION_ID;
import static com.rvalerio.foregroundappchecker.Constants.NOTIFICATION_TITLE;
import static com.rvalerio.foregroundappchecker.Constants.NOTIFICATION_TEXT;
import static com.rvalerio.foregroundappchecker.Constants.STOP_SERVICE;
import static com.rvalerio.foregroundappchecker.Constants.REQUEST_CODE;


public class ForegroundToastService extends Ability {

    private AppChecker appChecker;
    private CommonEventSubscriber stopServiceReceiver;
    private static final String TAG = ForegroundToastService.class.getSimpleName();
    private ToastDialog toast;
    private final int TOAST_DURATION = 1000;

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        startChecker();
        registerReceivers();
        createStickyNotification();
    }

    @Override
    protected void onStop() {
        super.onStop();
        stopChecker();
        unregisterReceivers();
        removeNotification();
        terminateAbility();
    }

    private void startChecker() {
        appChecker = new AppChecker();
        appChecker
                .when(getBundleName(), (String packageName) -> {
                    updateToast(packageName);
                })
                .whenOther((String pkgName) -> {
                        updateToast(pkgName);
                })
                .timeout(TIMEOUT)
                .start(this);
    }

    private void stopChecker() {
        appChecker.stop();
    }

    private void registerReceivers() {
        stopServiceReceiver = new CommonEventSubscriber(getCommonEventSubscribeInfo()) {
            @Override
            public void onReceiveEvent(CommonEventData commonEventData) {
                stopChecker();
                terminateAbility();
            }
        };
        try {
            CommonEventManager.subscribeCommonEvent(stopServiceReceiver);
        } catch (RemoteException remoteException) {
            LogUtil.error(TAG, "registerReceivers -> RemoteException");
        }
    }

    private void unregisterReceivers() {
        try {
            CommonEventManager.unsubscribeCommonEvent(stopServiceReceiver);
        } catch (RemoteException remoteException) {
            LogUtil.error(TAG, "unregisterReceivers -> RemoteException");
        }
    }

    private void createStickyNotification() {
        NotificationRequest notificationRequest = new NotificationRequest(NOTIFICATION_ID);
        notificationRequest.setLittleIcon(ResUtil.getPixelMap(getContext(), ResourceTable.Media_icon).get());
        notificationRequest.setInProgress(true);
        notificationRequest.setAlertOneTime(true);
        notificationRequest.setTapDismissed(false);
        notificationRequest.setDeliveryTime(0);
        notificationRequest.setContent(createNotificationContent(NOTIFICATION_TITLE, NOTIFICATION_TEXT));
        notificationRequest.setIntentAgent(createIntentAgent());

        try {
            NotificationHelper.publishNotification(notificationRequest);
        } catch (RemoteException ex) {
            LogUtil.error(TAG, "createStickyNotification -> RemoteException");
        }
    }

    private void removeNotification() {
        try {
            NotificationHelper.cancelNotification(NOTIFICATION_ID);
        } catch (RemoteException ex) {
            LogUtil.error(TAG, "removeNotification -> RemoteException");
        }
    }

    private NotificationRequest.NotificationContent createNotificationContent(String title, String text) {
        NotificationRequest.NotificationNormalContent content =
                new NotificationRequest.NotificationNormalContent().setTitle(title).setText(text);
        NotificationRequest.NotificationContent notificationContent =
                new NotificationRequest.NotificationContent(content);
        return notificationContent;
    }

    private IntentAgent createIntentAgent() {
        List<Intent> intents = new ArrayList<>();
        intents.add(new Intent().setAction(STOP_SERVICE));
        IntentAgentInfo agentInfo = new IntentAgentInfo(REQUEST_CODE, IntentAgentConstant.OperationType.SEND_COMMON_EVENT,
                IntentAgentConstant.Flags.UPDATE_PRESENT_FLAG, intents, new IntentParams());
        return IntentAgentHelper.getIntentAgent(getContext(), agentInfo);
    }

    private CommonEventSubscribeInfo getCommonEventSubscribeInfo() {
        MatchingSkills matchingSkills = new MatchingSkills();
        matchingSkills.addEvent(STOP_SERVICE);
        return new CommonEventSubscribeInfo(matchingSkills);
    }

    private void updateToast(String packageName) {
        toast = new ToastDialog(getContext());
        toast.setText(packageName);
        toast.setDuration(TOAST_DURATION);
        toast.show();
    }
}
